#include "QuickButtons.h"


QuickButtons::QuickButtons()
{
	buttonOpen = 0;
    animation = 0;

    opened = false;
    hotkeyOpened = false;
    
    normalWidth = 180;
    openedWidth = 600;	

    location.x = CW_USEDEFAULT;
    location.y = CW_USEDEFAULT;

	LoadSettings();
}


QuickButtons::~QuickButtons()
{
    SaveSettings();

	Deactivate();

    delete buttonOpen;
    buttonOpen = 0;

    if (!quickButtons.empty())
    {
        map<int, PaintedButton*>::iterator iter;
        for (iter = quickButtons.begin(); iter != quickButtons.end(); iter++)
        {
            delete iter->second;
        }
        quickButtons.clear();
    }
    
    delete animation;
    animation = 0;
}

void QuickButtons::Create(HINSTANCE hInstance)
{
	BOOL dwmEnabled;
	DwmIsCompositionEnabled(&dwmEnabled);

	CustomWindow::Create(hInstance,
					TEXT("QuickButtonsWindow"),
					WndProc,
					WS_EX_TOOLWINDOW,
					!dwmEnabled ? WS_POPUP : WS_THICKFRAME,
					!dwmEnabled ? CS_HREDRAW | CS_NOCLOSE | CS_DBLCLKS : CS_NOCLOSE | CS_DBLCLKS,
					!dwmEnabled ? GetSysColorBrush(COLOR_GRADIENTACTIVECAPTION) : GetStockBrush(BLACK_BRUSH),
					0,
					LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1)));

	this->SetText(Translate(TEXT("QuickButtons")));
	this->SetLocation(location);
	this->SetSize(opened ? openedWidth : normalWidth, 38, true);

	animation = new SmoothWindowSideAnimation(this->GetHWnd(), 0);

	buttonOpen = new PaintedButton(this->GetHWnd());
	buttonOpen->Clicked(buttonOpen_Clicked);
	buttonOpen->SetSize(28, 28);
	buttonOpen->SetLocation(this->normalWidth - 5 - buttonOpen->GetSize().cx, 5);
	buttonOpen->Show();
	
    map<int, int>::iterator iter;
	for (iter = quickButtonFunctions.begin(); iter != quickButtonFunctions.end(); iter++)
	{
		PaintedButton* tmpButton = new PaintedButton(this->GetHWnd());
		tmpButton->RightMouseButtonUp(quickButton_RightMouseButtonUp);
		tmpButton->Clicked(quickButton_Clicked);
		tmpButton->SetTextFormat(DT_CENTER | DT_VCENTER | DT_SINGLELINE);
		tmpButton->SetFontSize(16);

		TCHAR number[10] = {0};
		_stprintf(number, TEXT("%d"), iter->first + 1);
		tmpButton->SetText(number);

		tmpButton->SetTag((LPVOID)iter->first);
		tmpButton->SetLocation(normalWidth + 10 + iter->first * 50, 5);
		tmpButton->SetSize(50, this->GetSize().cy - 10);

		if (!dwmEnabled)
			tmpButton->SetTextColor(RGB(0, 0, 0));

		tmpButton->Show();
		quickButtons[iter->first] = tmpButton;
	}

	BOOL bl=TRUE;
	DwmSetWindowAttribute(this->GetHWnd(),DWMWA_DISALLOW_PEEK,&bl, sizeof(bl));
	DwmSetWindowAttribute(this->GetHWnd(),DWMWA_EXCLUDED_FROM_PEEK,&bl, sizeof(bl));

	DWMFLIP3DWINDOWPOLICY flip3DPolicy = DWMFLIP3D_EXCLUDEBELOW;
	DwmSetWindowAttribute(this->GetHWnd(), DWMWA_FLIP3D_POLICY, &flip3DPolicy, sizeof(DWMWA_FLIP3D_POLICY));	
}

CCState QuickButtons::Activate()
{
	CCState result;
    if ((result = CassiopeiaComponent::Activate()) != CCState::Successful)
        return result;

    Utilities::MoveWindowIntoVisibleArea(this->GetHWnd());
   
    this->ShowNoActivate();
    SetWindowPos(this->GetHWnd(), Utilities::GetLastValidTopLevelWindow(), 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);

    RegisterHotKey(this->GetHWnd(), 1, MOD_WIN, 81);

    return CCState::Successful;
}

CCState QuickButtons::Deactivate()
{
	CCState result;
    if ((result = CassiopeiaComponent::Deactivate()) != CCState::Successful)
        return result;

    this->Hide();

    UnregisterHotKey(this->GetHWnd(), 1);	

    return CCState::Successful;
}


void QuickButtons::Open(bool value)
{
    if (!animation->IsRunning())
    {
        if (value && !opened)	
        {
			animation->StartAnimation(60, normalWidth, openedWidth - normalWidth, WindowEdge::WE_WIDTH);
            opened = true;
        }
        else if (!value && opened)
        {
            animation->StartAnimation(44, openedWidth, normalWidth - openedWidth, WindowEdge::WE_WIDTH);
            opened = false;
        }

        buttonOpen->Refresh();
    }
}

void QuickButtons::ToggleOpen()
{
    Open(!opened);
}

bool QuickButtons::HandleQuickButtonWndProcs(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	if (!quickButtons.empty())
    {
        map<int, PaintedButton*>::iterator iter;
        for (iter = quickButtons.begin(); iter != quickButtons.end(); iter++)
        {
            if (iter->second && iter->second->HandleWndProc(hWnd, uMsg, wParam, lParam))
                return true;
        }
    }

    return false;
}

void QuickButtons::HandleQuickButtonsPainting(HDC hdc)
{
    if (!quickButtons.empty())
    {
        map<int, PaintedButton*>::iterator iter;
        for (iter = quickButtons.begin(); iter != quickButtons.end(); iter++)
        {
            if (iter->second)
                iter->second->HandlePainting(hdc);
        }
    }
}

HRESULT QuickButtons::ShowOpenFileDialog(HWND hwnd, LPTSTR * fileName)
{
    HRESULT hr = CoInitialize(0);

    if (SUCCEEDED(hr))
    {
        IFileDialog *fileDialog;
        
        hr = CoCreateInstance(CLSID_FileOpenDialog, 
                                      0, 
                                      CLSCTX_INPROC_SERVER, 
                                      IID_PPV_ARGS(&fileDialog));
        
        if (SUCCEEDED(hr))
        {
            hr = fileDialog->Show(hwnd);
            
            if (SUCCEEDED(hr))
            {
                IShellItem *result;
                hr = fileDialog->GetResult(&result);

                if (SUCCEEDED(hr))
                {
                    result->GetDisplayName(SIGDN_FILESYSPATH, fileName);
                    result->Release();
                }
            }
            fileDialog->Release();
        }
    }

    CoUninitialize();

    return hr;
}

HRESULT QuickButtons::ShowOpenFolderDialog(HWND hwnd, LPTSTR * folderName)
{
	HRESULT hr = CoInitialize(0);

	if (SUCCEEDED(hr))
	{
		IFileDialog *fileDialog;

		hr = CoCreateInstance(CLSID_FileOpenDialog, 
			0, 
			CLSCTX_INPROC_SERVER, 
			IID_PPV_ARGS(&fileDialog));

		if (SUCCEEDED(hr))
		{
			FILEOPENDIALOGOPTIONS options = {0};
			fileDialog->GetOptions(&options);
			fileDialog->SetOptions(options | FOS_PICKFOLDERS);
			hr = fileDialog->Show(hwnd);

			if (SUCCEEDED(hr))
			{
				IShellItem *result;
				hr = fileDialog->GetResult(&result);

				if (SUCCEEDED(hr))
				{
					result->GetDisplayName(SIGDN_FILESYSPATH, folderName);
					result->Release();
				}
			}
			fileDialog->Release();
		}
	}

	CoUninitialize();

	return hr;
}

void QuickButtons::LoadSettings()
{
    Settings settings;
    Settings::Data data = {0};
    settings.Load(&data);

    location = data.QuickButtonsData.Location;
    opened = data.QuickButtonsData.Opened;

    if (data.QuickButtonsData.Functions.empty())
    {
		for (int i = 0; i < 8; i++)
		{
			quickButtonFunctions[i] = 0;
		}
    }
    else
    {
        quickButtonFunctions = data.QuickButtonsData.Functions;
    }

	quickButtonType1Commands = data.QuickButtonsData.Type1Commands;
}

void QuickButtons::SaveSettings()
{
    Settings settings;
    Settings::Data data = {0};
    settings.Load(&data);

    data.QuickButtonsData.Location = this->GetLocation();
    data.QuickButtonsData.Opened = opened;
    data.QuickButtonsData.Functions = quickButtonFunctions;
    data.QuickButtonsData.Type1Commands = quickButtonType1Commands;

    settings.Save(data);
}

void QuickButtons::ChangeDwmCompatibleLayout()
{
    BOOL dwmEnabled;
    DwmIsCompositionEnabled(&dwmEnabled);

    if (dwmEnabled)
    {
        SetClassLongPtr(this->GetHWnd(),GCL_HBRBACKGROUND,(LONG)GetStockObject(BLACK_BRUSH));
        SetClassLongPtr(this->GetHWnd(),GCL_STYLE, GetClassLongPtr(this->GetHWnd(), GCL_STYLE) & ~CS_HREDRAW);

        SetWindowLongPtr(this->GetHWnd(), GWL_STYLE, GetWindowLongPtr(this->GetHWnd(), GWL_STYLE) & ~WS_POPUP);
        SetWindowLongPtr(this->GetHWnd(), GWL_STYLE, GetWindowLongPtr(this->GetHWnd(), GWL_STYLE) | WS_THICKFRAME);
        SetWindowLongPtr(this->GetHWnd(), GWL_STYLE, GetWindowLongPtr(this->GetHWnd(), GWL_STYLE) | WS_CAPTION);


		if (!quickButtons.empty())
        {
            map<int, PaintedButton*>::iterator iter;
            for (iter = quickButtons.begin(); iter != quickButtons.end(); iter++)
            {
                if (iter->second)
                    iter->second->SetTextColor(RGB(255, 255, 255));
            }
        }
    }
    else
    {
        SetClassLongPtr(this->GetHWnd(),GCL_HBRBACKGROUND,(LONG)GetSysColorBrush(COLOR_GRADIENTACTIVECAPTION));
        SetClassLongPtr(this->GetHWnd(),GCL_STYLE, GetClassLongPtr(this->GetHWnd(), GCL_STYLE) | CS_HREDRAW);

        SetWindowLongPtr(this->GetHWnd(), GWL_STYLE, GetWindowLongPtr(this->GetHWnd(), GWL_STYLE) | WS_POPUP);
        SetWindowLongPtr(this->GetHWnd(), GWL_STYLE, GetWindowLongPtr(this->GetHWnd(), GWL_STYLE) & ~WS_THICKFRAME);
        SetWindowLongPtr(this->GetHWnd(), GWL_STYLE, GetWindowLongPtr(this->GetHWnd(), GWL_STYLE) & ~WS_CAPTION);

        if (!quickButtons.empty())
        {
            map<int, PaintedButton*>::iterator iter;
            for (iter = quickButtons.begin(); iter != quickButtons.end(); iter++)
            {
                if (iter->second)
                    iter->second->SetTextColor(RGB(0, 0, 0));
            }
        }
    }

	this->Refresh();
}


void QuickButtons::buttonOpen_Clicked(PaintedButton* sender, LPVOID tag)
{
    QuickButtons* instance = (QuickButtons*)instances[sender->GetParentWindow()];
    instance->hotkeyOpened = false;
    instance->ToggleOpen();
}

void QuickButtons::quickButton_Clicked(PaintedButton* sender, LPVOID tag)
{
    QuickButtons* instance = (QuickButtons*)instances[sender->GetParentWindow()];

	int buttonId = (int)tag;

	if (instance->quickButtonFunctions.find(buttonId) != instance->quickButtonFunctions.end())
	{
		switch (instance->quickButtonFunctions[buttonId])
		{
		case 1:
			{
				//run a program
				if (instance->quickButtonType1Commands.find(buttonId) != instance->quickButtonType1Commands.end())
				{
					TCHAR path[_MAX_PATH]={0};
					TCHAR drive[_MAX_DRIVE]={0};
					TCHAR dir[_MAX_DIR]={0};

					_tsplitpath(instance->quickButtonType1Commands[buttonId].c_str(), drive, dir, 0, 0);
					_tmakepath(path, drive, dir, 0, 0);

					ShellExecute(0, 0, instance->quickButtonType1Commands[buttonId].c_str(), 0, path, SW_SHOWDEFAULT);			
				}			

				break;
			}
		case 2:
			{
				//start the screensaver
				PostMessage(instance->GetHWnd(), WM_SYSCOMMAND, SC_SCREENSAVE, 0);
				
				break;
			}
		case 3:
			{
				//shutdown the display
				PostMessage(instance->GetHWnd(), WM_SYSCOMMAND, SC_MONITORPOWER, 2);
				
				break;
			}
		case 4:
			{
				//Swap MouseButtons
				if (SwapMouseButton(TRUE))
					SwapMouseButton(FALSE);

				break;
			}
		case 5:
			{
				//open a folder
				if (instance->quickButtonType1Commands.find(buttonId) != instance->quickButtonType1Commands.end())
				{
					ShellExecute(0, 0, instance->quickButtonType1Commands[buttonId].c_str(), 0, instance->quickButtonType1Commands[buttonId].c_str(), SW_SHOWDEFAULT);			
				}			

				break;
			}
		}
	}
}

void QuickButtons::quickButton_RightMouseButtonUp(PaintedButton* sender, LPVOID tag)
{
    QuickButtons* instance = (QuickButtons*)instances[sender->GetParentWindow()];
	
	int buttonId = (int)tag;
    
    POINT cursorPos = Utilities::GetCursorPosition();

	HMENU hMenu = CreatePopupMenu();
	AppendMenu(hMenu, MF_STRING, 2, Translate(TEXT("Start Screensaver")).c_str());
	AppendMenu(hMenu, MF_STRING, 3, Translate(TEXT("Poweroff Display")).c_str());
	AppendMenu(hMenu, MF_STRING, 4, Translate(TEXT("Swap Mousebuttons")).c_str());
	AppendMenu(hMenu, MF_SEPARATOR, 0, 0);
	

	//Open Folder
	if (instance->quickButtonFunctions.find(buttonId) != instance->quickButtonFunctions.end() && instance->quickButtonFunctions[buttonId] == 5
		&& instance->quickButtonType1Commands.find(buttonId) != instance->quickButtonType1Commands.end())
	{
		TCHAR folderName[_MAX_FNAME] = {0};
		_tsplitpath(instance->quickButtonType1Commands[buttonId].c_str(), 0, 0, folderName, 0);

		TCHAR text[_MAX_FNAME + 2] = {0};
		_stprintf(text, Translate(TEXT("Open %s")).c_str(), folderName);

		AppendMenu(hMenu, MF_STRING, 5, text);
	}
	else
	{
		AppendMenu(hMenu, MF_STRING, 5, Translate(2, TEXT("Open Folder"), TEXT("#...")).c_str());
	}

	//Run
	if (instance->quickButtonFunctions.find(buttonId) != instance->quickButtonFunctions.end() && instance->quickButtonFunctions[buttonId] == 1
		&& instance->quickButtonType1Commands.find(buttonId) != instance->quickButtonType1Commands.end())
	{
		TCHAR fileName[_MAX_FNAME] = {0};
		_tsplitpath(instance->quickButtonType1Commands[buttonId].c_str(), 0, 0, fileName, 0);

		TCHAR text[_MAX_FNAME + 2] = {0};
		_stprintf(text, Translate(TEXT("Run %s")).c_str(), fileName);

		AppendMenu(hMenu, MF_STRING, 1, text);
	}
	else
	{
		AppendMenu(hMenu, MF_STRING, 1, Translate(2, TEXT("Run"), TEXT("#...")).c_str());
	}	



	if (instance->quickButtonFunctions.find(buttonId) != instance->quickButtonFunctions.end())
		CheckMenuItem(hMenu, instance->quickButtonFunctions[buttonId], MF_CHECKED);

	UINT_PTR menuId = TrackPopupMenu(hMenu, TPM_RETURNCMD | TPM_NONOTIFY | TPM_VERNEGANIMATION | TPM_LEFTBUTTON, cursorPos.x, cursorPos.y, 0, instance->GetHWnd(), 0);

	if (instance->quickButtonFunctions.find(buttonId) != instance->quickButtonFunctions.end() && instance->quickButtonFunctions[buttonId] == menuId)
	{
		//set no function
		instance->quickButtonFunctions[buttonId] = 0;
	}
	else if (menuId != 0)
	{
		if (menuId == 1)
		{
			LPTSTR fileName;
			HRESULT hr = instance->ShowOpenFileDialog(instance->GetHWnd(), &fileName);	

			if (SUCCEEDED(hr))
			{
				instance->quickButtonType1Commands[buttonId] = fileName;
				instance->quickButtonFunctions[buttonId] = menuId;
			}
		}
		else if (menuId == 5)
		{
			LPTSTR fileName;
			HRESULT hr = instance->ShowOpenFolderDialog(instance->GetHWnd(), &fileName);	

			if (SUCCEEDED(hr))
			{
				instance->quickButtonType1Commands[buttonId] = fileName;
				instance->quickButtonFunctions[buttonId] = menuId;
			}
		}
		else
		{
			instance->quickButtonFunctions[buttonId] = menuId;
		}
	}

	DestroyMenu(hMenu);
}


LRESULT CALLBACK QuickButtons::WndProc(LPVOID sender, HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
    static BOOL	dwmEnabled = -1;
    static bool hotkeyPressed = false;

	QuickButtons* instance = (QuickButtons*)((CustomWindow*)sender);

    if (dwmEnabled == -1)
        DwmIsCompositionEnabled(&dwmEnabled);


    if (instance->buttonOpen->HandleWndProc(hWnd, uMsg, wParam, lParam))
        return DefWindowProc(hWnd, uMsg, wParam, lParam);

	if (instance->HandleQuickButtonWndProcs(hWnd, uMsg, wParam, lParam))
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
    
    switch (uMsg)
    {
    case WM_KEYUP:
        {
            if (!instance->IsActive())
                break;

            if (wParam == 'Q' && hotkeyPressed)
            {
                hotkeyPressed = false;
                break;
            }

            if ((wParam == VK_NUMPAD1 || wParam == '1') && instance->quickButtons.find(0) != instance->quickButtons.end())
                instance->quickButtons[0]->PerformClick();
            else if ((wParam == VK_NUMPAD2 || wParam == '2') && instance->quickButtons.find(1) != instance->quickButtons.end())
                instance->quickButtons[1]->PerformClick();
            else if ((wParam == VK_NUMPAD3 || wParam == '3') && instance->quickButtons.find(2) != instance->quickButtons.end())
                instance->quickButtons[2]->PerformClick();
            else if ((wParam == VK_NUMPAD4 || wParam == '4') && instance->quickButtons.find(3) != instance->quickButtons.end())
                instance->quickButtons[3]->PerformClick();
            else if ((wParam == VK_NUMPAD5 || wParam == '5') && instance->quickButtons.find(4) != instance->quickButtons.end())
                instance->quickButtons[4]->PerformClick();
			else if ((wParam == VK_NUMPAD6 || wParam == '6') && instance->quickButtons.find(5) != instance->quickButtons.end())
                instance->quickButtons[5]->PerformClick();
			else if ((wParam == VK_NUMPAD7 || wParam == '7') && instance->quickButtons.find(6) != instance->quickButtons.end())
                instance->quickButtons[6]->PerformClick();
			else if ((wParam == VK_NUMPAD8 || wParam == '8') && instance->quickButtons.find(7) != instance->quickButtons.end())
                instance->quickButtons[7]->PerformClick();
            break;
        }
    case WM_HOTKEY:
        {
            if (wParam == 1)
            {
                hotkeyPressed = true;
                Utilities::MoveWindowIntoVisibleArea(hWnd);
                SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
                SetForegroundWindow(hWnd);

                if (!instance->opened)
                {
                    instance->hotkeyOpened = true;
                    instance->Open(true);
                }
            }

            break;
        }
    case WM_ACTIVATE:
        {
            if (wParam == WA_INACTIVE)
            {
                SetWindowPos(hWnd, Utilities::GetLastValidTopLevelWindow(), 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);

                if (instance->hotkeyOpened)
                {
                    instance->Open(false);
                    instance->hotkeyOpened = false;
                }
            }
			else
			{
				instance->Refresh();
			}

            break;
        }
    case WM_LBUTTONDBLCLK:
        {
            instance->hotkeyOpened = false;
            instance->ToggleOpen();
            break;
        }
    case WM_LBUTTONDOWN:
        {
            SendMessage(hWnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, 0);

            //in "case WM_MOUSEMOVE:"
            /*if (wParam == MK_LBUTTON)
            SendMessage(hWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0);*/

            break;
        }
    case WM_DWMCOMPOSITIONCHANGED:
        {
            DwmIsCompositionEnabled(&dwmEnabled);
            instance->ChangeDwmCompatibleLayout();
            break;
        }
    case WM_MOVING:
        {
            if (instance->animation && instance->animation->IsRunning())
            {
                //disable moving during the animation, otherwise the animation would be
                //cancelled when moving the window during the animation progress

                RECT cb = instance->GetBounds();
                RECT* r = (RECT*)lParam;

                r->left = cb.left;
                r->top = cb.top;
                r->right = cb.right;
                r->bottom = cb.bottom;

                return TRUE;
            }

            break;
        }
    case WM_PAINT:
        {		
            HDC          hdc;
            PAINTSTRUCT  ps;

            hdc = BeginPaint(hWnd, &ps);

            RECT clientRect;
            GetClientRect(hWnd,&clientRect);	

            clientRect.right = instance->normalWidth;

            //draw text
            Utilities::DrawDwmCompatibleText(clientRect, hdc, instance->GetText().c_str(), 13, RGB(0, 0, 0), DT_LEFT | DT_VCENTER | DT_SINGLELINE, FW_MEDIUM, 12, 9, 0);
            
            //draw vertical line
            Graphics graphics(hdc);
            graphics.SetSmoothingMode(SmoothingModeAntiAlias);
            Pen pen1(Color(80, 30, 30, 30));
            Pen pen2(Color(80, 240, 240, 240));
            graphics.DrawLine(&pen1, instance->normalWidth + 1, 8, instance->normalWidth + 1, instance->GetSize().cy - 8);
            graphics.DrawLine(&pen2, instance->normalWidth + 2, 8, instance->normalWidth + 2, instance->GetSize().cy - 8);

            //draw dwmDisabled Color
            if (!dwmEnabled)
            {
                Pen border1(Color(0, 0, 0));
                Pen border2(Color(230, 230, 230));
                graphics.DrawRectangle(&border1, 0, 0, instance->GetSize().cx - 1, instance->GetSize().cy - 1);
                graphics.DrawRectangle(&border2, 1, 1, instance->GetSize().cx - 3, instance->GetSize().cy - 3);
            }

            //draw arrow
            if (dwmEnabled)
                Utilities::DrawPNGFromResource(instance->hInstance, hdc, MAKEINTRESOURCE(instance->opened ? IDB_ArrowLeft : IDB_ArrowRight), instance->normalWidth - 5 - instance->buttonOpen->GetSize().cx + ((instance->buttonOpen->GetSize().cx - 12) / 2), 5 + ((instance->buttonOpen->GetSize().cx - 12) / 2), 12, 12);
            else
                Utilities::DrawPNGFromResource(instance->hInstance, hdc, MAKEINTRESOURCE(instance->opened ? IDB_ArrowBlackLeft : IDB_ArrowBlackRight), instance->normalWidth - 5 - instance->buttonOpen->GetSize().cx + ((instance->buttonOpen->GetSize().cx - 12) / 2), 5 + ((instance->buttonOpen->GetSize().cx - 12) / 2), 12, 12);

            
            //button painting
            instance->buttonOpen->HandlePainting(hdc);
			instance->HandleQuickButtonsPainting(hdc);
            
            EndPaint(hWnd, &ps);

			break;
        }
    case WM_DISPLAYCHANGE:
        {
            instance->Refresh();
            break;
        }
	case WM_SIZE:
		{
            Utilities::MoveWindowIntoVisibleArea(hWnd);
			break;
		}
    }

    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
